package com.ylr.job.biz.client;


import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.ylr.grpc.ExecutorBiz.ExecutorBizGrpc;
import com.ylr.grpc.ExecutorBiz.ExecutorBizProto;
import com.ylr.job.biz.model.*;
import com.ylr.job.util.XxlJobRemotingUtil;
import io.grpc.Channel;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.StatusRuntimeException;
import io.grpc.stub.StreamObserver;

import java.util.concurrent.TimeUnit;

/**
 * admin api test
 *
 * @author xuxueli 2017-07-28 22:14:52
 *
 * 客户端进行远程调用
 */
public class ExecutorBizProtoClient {
    //private final GreeterGrpc.GreeterBlockingStub greeterBlocStub;
    private final ExecutorBizGrpc.ExecutorBizBlockingStub executorBizBlockingStub;

    /**
     * 构造使用现有通道访问服务端的客户端
     */
    public ExecutorBizProtoClient(Channel channel) {
        // 'channel'在这里是Channel,而不是ManagedChannel,所有它负责关闭

        // 向代码传递通道可以使代码更容易测试，也可以更容易地重用通道。
        // 同时这里创建的是同步(阻塞)RPC服务。
        //greeterBlocStub = GreeterGrpc.newBlockingStub(channel);
        executorBizBlockingStub = ExecutorBizGrpc.newBlockingStub(channel);
    }

    /** 向服务端发送请求 */
    public String beat() {

        System.out.println("beat 测试!!!!");
        ExecutorBizProto.HelloRequest request = ExecutorBizProto.HelloRequest.newBuilder().setName("beat 测试").build();
        ExecutorBizProto.ResultReply response;
        try {
//            response = greeterBlocStub.sayHello(request);
            response = executorBizBlockingStub.beat(request);
        } catch (StatusRuntimeException e) {
            System.out.println("WARNING, RPC failed: Status=" + e.getStatus());
            return "error!";
        }
        Gson gson = new Gson();
        System.out.println("beat 测试成功 结果是: " +  gson.toJson(response));
//        return XxlJobRemotingUtil.postBody(addressUrl+"beat", accessToken, timeout, "", String.class);
        return "ok!";
    }

    public ReturnT<String> idleBeat(IdleBeatParam idleBeatParam){
//        return XxlJobRemotingUtil.postBody(addressUrl+"idleBeat", accessToken, timeout, idleBeatParam, String.class);
        return null;

    }

    public ReturnT<String> run(TriggerParam triggerParam) {
        System.out.println("run 测试!!!!");
        ExecutorBizProto.TriggerParamRequest triggerParamRequest = ExecutorBizProto.TriggerParamRequest.newBuilder()
                .setJobId(triggerParam.getJobId())
                .setExecutorHandler(triggerParam.getExecutorHandler())
                .setExecutorParams(triggerParam.getExecutorParams())
                .setExecutorBlockStrategy(triggerParam.getExecutorBlockStrategy())
                .setExecutorTimeout(triggerParam.getExecutorTimeout())
                .setLogId(triggerParam.getLogId())
                .setLogDateTime(triggerParam.getLogDateTime())
                .setGlueType(triggerParam.getGlueType())
                .setGlueSource(triggerParam.getGlueSource())
                .setGlueUpdatetime(triggerParam.getGlueUpdatetime())
                .setBroadcastIndex(triggerParam.getBroadcastIndex())
                .setBroadcastTotal(triggerParam.getBroadcastTotal()).build();
        ExecutorBizProto.ResultReply response;
        try {
            response = executorBizBlockingStub.run(triggerParamRequest);
        } catch (StatusRuntimeException e) {
            System.out.println("WARNING, RPC failed: Status=" + e.getStatus());
            return new ReturnT<String>(ReturnT.FAIL_CODE, "xxl-rpc remoting (JobId="+triggerParam.getJobId()+") response content invalid.");
        }
        Gson gson = new Gson();
        System.out.println("run 测试成功 结果是: " +  gson.toJson(response));
        return new ReturnT<String>(gson.toJson(response));


    }

    public ReturnT<String> kill(KillParam killParam) {
        return null;
    }

    public ReturnT<LogResult> log(LogParam logParam) {
        return null;
    }


    /**
     * 客户端启动入口，可以支持填写2个参数，否则使用默认值。 第1个参数是用户名。 第2个参数是目标服务器，格式IP:Port。
     */
    public static void main(String[] args) throws Exception {
        String user = "world";
        // 访问本机在50051端口上运行的服务
        String target = "localhost:50051";
        // 命令行用法帮助，允许将用户名和目标服务器作为命令行参数传入。
        if (args.length > 0) {
            if ("--help".equals(args[0])) {
                System.err.println("Usage: [name [target]]");
                System.err.println("");
                System.err.println("  name    The name you wish to be greeted by. Defaults to " + user);
                System.err.println("  target  The server to connect to. Defaults to " + target);
                System.exit(1);
            }
            user = args[0];
        }
        if (args.length > 1) {
            target = args[1];
        }

        // 创建到服务器的通信通道，通道是线程安全的和可重用的。
        // 通常在应用程序开始时创建通道，并重用直到应用程序关闭。
        ManagedChannel channel = ManagedChannelBuilder.forTarget(target).usePlaintext().build();
        try {
            ExecutorBizProtoClient client = new ExecutorBizProtoClient(channel);
            System.out.println(client.beat());
        } finally {
            // ManagedChannel使用像线程和TCP连接这样的资源。
            // 为了防止泄漏这些资源，通道应该在不再使用时关闭。
            channel.shutdownNow().awaitTermination(5, TimeUnit.SECONDS);
        }
    }
}
